﻿using System;
using System.Diagnostics.Contracts;
using System.Web;
using OpenWaves.Web;

namespace OpenWaves.Pagination
{
    public class PaginationUrlFactory : IPaginationUrlFactory, ICurrentPageIndexProvider
    {
        private readonly HttpRequest request;
        private readonly string pageNumberParameterName;

        public PaginationUrlFactory(HttpRequest request)
            : this(request, "p")
        {
        }

        public PaginationUrlFactory(HttpRequest request, string pageNumberParameterName)
        {
            Contract.Requires<ArgumentNullException>(request != null);
            Contract.Requires<ArgumentNullException>(String.IsNullOrEmpty(pageNumberParameterName) == false);

            this.request = request;
            this.pageNumberParameterName = pageNumberParameterName;
        }

        public Url GetPageUrl(int pageIndex)
        {
            Contract.Requires<ArgumentOutOfRangeException>(pageIndex >=0);
            Contract.Ensures(Contract.Result<Url>() != null);

            return this.request.Url.GetBuilder().SetParameter(this.pageNumberParameterName, pageIndex + 1).ToUrl();
        }

        public int CurrentPageIndex
        {
            get
            {
                Contract.Ensures(Contract.Result<int>() >= 0);
                return ParseCurrentPageIndex(this.request.GetRawUrl(), this.pageNumberParameterName);
            }
        }

        private static int ParseCurrentPageIndex(Url url, string pageNumberParameterName)
        {
            string pageNumberString;
            if (url.Query.TryGetValue(pageNumberParameterName, out pageNumberString))
            {
                int pageNumber;
                if (Int32.TryParse(pageNumberString, out pageNumber))
                {
                    return Math.Max(0, pageNumber - 1);
                }
            }

            return 0;
        }
    }
}